package mspbots.xero.client.core.data.reports;

import com.fasterxml.jackson.databind.JsonNode;
import lombok.extern.log4j.Log4j2;
import mspbots.xero.client.core.AbstractToolsUtil;
import mspbots.xero.client.core.client.ResultData;
import mspbots.xero.client.core.data.BaseSyncService;
import mspbots.xero.client.oauth.TokenState;
import mspbots.xero.common.QueryParams;
import mspbots.xero.common.RabbitKeys;
import mspbots.xero.common.ResultMsg;
import mspbots.xero.common.ResultSync;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;

/**
 * com.mspbots.sync.scheduled.service.UserService
 *
 * @author Alex bob(https://github.com/vnobo)
 * @date Created by 2019/6/11
 */
@Log4j2
@Service
public class BalanceSheetServiceImpl extends AbstractToolsUtil implements BaseSyncService {


    public Flux<ResultData> find(Long tenantId, QueryParams queryParams) {
        ResultSync resultSync = ResultSync.withDefault("USERS-SEARCH");
        return this.loadToken(tenantId)
                .flatMapMany(tokenState -> this.get(queryParams)
                        .contextWrite(ctx -> ctx.put("tokenState", tokenState)))
                .contextWrite(ctx -> ctx.put("resultSync", resultSync));
    }

    public Mono<JsonNode> count(Long tenantId, QueryParams queryParams) {
        ResultSync resultSync = ResultSync.withDefault("USERS-COUNT");
        return super.loadToken(tenantId)
                .flatMap(clientProperties -> this.count(clientProperties, queryParams))
                .contextWrite(ctx -> ctx.put("resultSync", resultSync));
    }

    private Mono<JsonNode> count(TokenState properties, QueryParams queryParams) {
        return Mono.empty();
    }

    @Override
    public Mono<Void> syncFast(TokenState tokenState) {
        ResultSync resultSync = ResultSync.withDefault("REPORTS-BALANCE-SHEET-SYNC");
        return this.get(QueryParams.withDefault())
                .contextWrite(ctx -> ctx.put("tokenState", tokenState))
                .contextWrite(ctx -> ctx.put("resultSync", resultSync))
                .doOnNext(this::syncResult)
                .then();
    }

    private void syncResult(ResultData resultData) {
        this.sendEntity(RabbitKeys.REPORTS_SYNC_QUEUE_KEY, ResultMsg.builder()
                .xeroTenantId(resultData.getXeroTenantId())
                .tenantId(resultData.getTenantId())
                .id(resultData.getEntity().get("Id").textValue())
                .action("BalanceSheet").entity(resultData.getEntity())
                .syncDate(LocalDateTime.now()).build());
    }

    private Flux<ResultData> get(QueryParams queryParams) {
        return super.xeroClient.get("/api.xro/2.0/Reports/BalanceSheet", queryParams);
    }

}
